"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const defines_1 = require("../lib/defines");
const Classrooms_1 = require("../lib/Classrooms");
const Member_1 = require("../lib/Member");
const enums_1 = require("../utils/enums");
const socket_message_1 = require("../utils/socket_message");
const log4js_1 = require("log4js");
const logger = (0, log4js_1.getLogger)('Forward');
function forward(app) {
    const { socket, clientUtils } = app.locals;
    const { userId, username } = socket.handshake.query;
    const { forwarding, forward, forwardingReceive, forwardJoin, forwardJoined } = defines_1.RequestMethod;
    const owner = { userId, username };
    socket.on(forwarding, function forwardMember(data, cb) {
        const { room, sender, receiver } = data;
        const { intercom } = app.locals;
        const classroom = Classrooms_1.Classrooms.get(room.classId);
        const __receiver = Member_1.Members.get(receiver.userId);
        const __receiver_socket = intercom[receiver.userId];
        const forwarding_error = (msg) => (0, socket_message_1.errorMsg)(forward, msg, { owner });
        if (!classroom) {
            return cb && cb(forwarding_error('room not find!'));
        }
        logger.debug(forwarding, JSON.stringify(room, null, 2), JSON.stringify(__receiver, null, 2));
        try {
            const forwardOptions = {
                sender,
                room: {
                    ...classroom.json(),
                    conferenceMode: "DEFAULT",
                    inviteMode: "NO_VERIFY",
                    joinMode: "NO_VERIFY",
                },
                mediaOptions: classroom.getMediaOption(),
            };
            socket
                .to(__receiver_socket.id)
                .timeout(1000 * 60 * 3)
                .emit(forwardingReceive, forwardOptions, (error, [data]) => {
                if (error) {
                    socket.emit(forward, (0, socket_message_1.timeoutMsg)(forward, error));
                    return;
                }
                const inviteAgree = {
                    data: receiver,
                    status: data === null || data === void 0 ? void 0 : data.status
                };
                socket.emit(`${forward}:agree`, inviteAgree);
            });
            if (cb) {
                cb((0, socket_message_1.okMsg)(forward));
            }
        }
        catch (error) {
            cb && cb(forwarding_error(error));
            logger.error('forward: -> ', error === null || error === void 0 ? void 0 : error.toString());
        }
    });
    socket.on(forwardJoin, async function forwardJoinRoom({ offer, member: sender, room }, cb) {
        var _a;
        const { classId } = room;
        const forward_join_error = (msg) => (0, socket_message_1.errorMsg)(forwardJoined, msg);
        const classroom = Classrooms_1.Classrooms.get(classId);
        const self = Member_1.Members.get(userId);
        if (!classroom) {
            return (0, socket_message_1.errorMsg)('forward:reject', 'room not find!');
        }
        logger.debug((_a = Member_1.Members.toArray()) === null || _a === void 0 ? void 0 : _a.toString());
        const __member = Member_1.Members.get(sender.userId);
        if (!__member) {
            return cb && cb(forward_join_error('member not find!'));
        }
        let candidatesQueue = self.candidatesQueue[userId] || (self.candidatesQueue[userId] = []);
        logger.debug('forwardJoin: => ', forwardJoin === null || forwardJoin === void 0 ? void 0 : forwardJoin.toString());
        const fromEndpoint = __member.getEndpoint(room.classId, sender.userId);
        const toEndpoint = await clientUtils.createEndpoint(classroom.pipeline);
        __member.setEndpoint(room.classId, userId, toEndpoint);
        logger.debug('forwardJoin: => ', '设置节点');
        self.state = enums_1.MemberStateEnums.BUSY;
        while (candidatesQueue.length) {
            const candidate = candidatesQueue.shift();
            logger.debug('iceCandidate: => ', '消费缓存2 ice');
            toEndpoint.addIceCandidate(candidate);
        }
        logger.debug('forwardJoin: => ', '交换 ice');
        clientUtils.onIceCandidate(toEndpoint, (iceCandidate) => {
            socket.emit('iceCandidate', { iceCandidate, member: sender });
        });
        logger.debug('forwardJoin: => ', '创建 answer');
        clientUtils.processOffer(toEndpoint, offer, async (sdpAnswer) => {
            if (fromEndpoint) {
                logger.debug('offer', '建立连接');
                clientUtils.connect(fromEndpoint, toEndpoint);
            }
            __member.setEndpoint(room.classId, userId, toEndpoint);
            socket.emit('answer', { sdpAnswer, member: sender });
            logger.debug('offer', 'answer');
        });
        if (cb) {
            cb((0, socket_message_1.okMsg)('inviteAgree'));
        }
    });
}
exports.default = forward;
